package lion.framework.core.web.views;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lion.dev.lang.MapJ;
import lion.framework.core.conf.Config;
import lion.framework.core.conf.ConfigManager;
import lion.framework.core.web.anno.ViewType;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

/**
 * 
 * 参数 name 下载的zip文件名
 * 
 * 参数 files 下载的文件列表
 * 
 * 参数 entries 压缩的文件文件项，每一项包含文件名称和文件内容，内容可以是一个输入流，也可以是一个文件,其他的将会忽略
 * 
 * @author lion
 * @email hl_0074@sina.com
 * @date 2015年4月23日
 */
@ViewType("zip")
public class ZipView implements IView {

	private static final String VIEW_TYPE = "zip";

	private String name;

	@SuppressWarnings("unchecked")
	@Override
	public void render(HttpServletRequest request, HttpServletResponse response) throws Exception {

		String name = (String) request.getAttribute("name");

		if (StringUtils.isBlank(name)) {
			name = "download.zip";
		}

		// 列表项
		List<MapJ> entries = (List<MapJ>) request.getAttribute("entries");
		if (entries == null) {
			entries = new ArrayList<>();
		}
		// 文件列表
		List<File> files = (List<File>) request.getAttribute("files");
		if (files != null) {
			for (File file : files) {
				MapJ item = new MapJ();
				item.put("name", file.getName());
				item.put("content", file);
				entries.add(item);
			}
		}
		response.setContentType("application/zip");
		Config config = ConfigManager.getConfig("framework");
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name, config.getString("framework.sysencoding", "UTF-8")));

		outputEntries(entries, response);
	}

	private void outputEntries(List<MapJ> entries, HttpServletResponse response) throws IOException {

		ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());

		for (MapJ item : entries) {

			Object o = item.get("content");
			if (o == null) {
				continue;
			}

			InputStream ins = null;

			if (o instanceof File) {
				try {
					ins = new FileInputStream((File) o);
				} catch (Exception e) {
				}
			} else if (o instanceof InputStream) {
				ins = (InputStream) o;
			}

			if (ins == null) {
				continue;
			}
			try {
				ZipEntry ze = new ZipEntry(item.getString("name"));
				zos.putNextEntry(ze);
				IOUtils.copy(ins, zos);
			} catch (Exception e) {
			} finally {
				ins.close();
			}

		}
		zos.flush();
		zos.close();
	}

	@Override
	public String getName() {

		return this.name;
	}

	@Override
	public String type() {

		return VIEW_TYPE;
	}
}
